#!/usr/bin/env python3
"""
前后端联调测试脚本
测试推荐系统的完整流程
"""

import asyncio
import requests
import json
from datetime import datetime

class IntegrationTester:
    """前后端联调测试器"""
    
    def __init__(self, base_url="http://localhost:8000"):
        self.base_url = base_url
        self.session = requests.Session()
        self.token = None
        self.user_id = None
    
    def test_backend_health(self):
        """测试后端健康状态"""
        print("🔍 测试后端健康状态...")
        
        try:
            response = self.session.get(f"{self.base_url}/health")
            if response.status_code == 200:
                print("✅ 后端服务运行正常")
                return True
            else:
                print(f"❌ 后端服务异常: {response.status_code}")
                return False
        except Exception as e:
            print(f"❌ 后端连接失败: {e}")
            return False
    
    def test_user_registration(self):
        """测试用户注册"""
        print("🔍 测试用户注册...")
        
        try:
            # 生成测试用户数据
            phone = f"138{datetime.now().strftime('%H%M%S')}"
            username = f"test_user_{datetime.now().strftime('%H%M%S')}"
            
            register_data = {
                "phone": phone,
                "username": username,
                "password": "123456",
                "nickname": "测试用户"
            }
            
            response = self.session.post(f"{self.base_url}/api/auth/register", json=register_data)
            
            if response.status_code == 200:
                result = response.json()
                if result.get("code") == 0:
                    print(f"✅ 用户注册成功: {username}")
                    return True
                else:
                    print(f"❌ 用户注册失败: {result.get('msg')}")
                    return False
            else:
                print(f"❌ 用户注册请求失败: {response.status_code}")
                return False
                
        except Exception as e:
            print(f"❌ 用户注册异常: {e}")
            return False
    
    def test_user_login(self):
        """测试用户登录"""
        print("🔍 测试用户登录...")
        
        try:
            login_data = {
                "username": "test_user",
                "password": "123456"
            }
            
            response = self.session.post(f"{self.base_url}/api/auth/login-password", json=login_data)
            
            if response.status_code == 200:
                result = response.json()
                if result.get("code") == 0:
                    self.token = result.get("data", {}).get("token")
                    self.user_id = result.get("data", {}).get("user", {}).get("id")
                    print("✅ 用户登录成功")
                    return True
                else:
                    print(f"❌ 用户登录失败: {result.get('msg')}")
                    return False
            else:
                print(f"❌ 用户登录请求失败: {response.status_code}")
                return False
                
        except Exception as e:
            print(f"❌ 用户登录异常: {e}")
            return False
    
    def test_get_tags(self):
        """测试获取标签列表"""
        print("🔍 测试获取标签列表...")
        
        try:
            response = self.session.get(f"{self.base_url}/api/tags")
            
            if response.status_code == 200:
                result = response.json()
                if isinstance(result, list) and len(result) > 0:
                    print(f"✅ 获取标签成功，共 {len(result)} 个标签")
                    return result
                else:
                    print("❌ 标签列表为空")
                    return []
            else:
                print(f"❌ 获取标签失败: {response.status_code}")
                return []
                
        except Exception as e:
            print(f"❌ 获取标签异常: {e}")
            return []
    
    def test_set_user_tags(self, tags):
        """测试设置用户标签"""
        print("🔍 测试设置用户标签...")
        
        if not self.token:
            print("❌ 用户未登录")
            return False
        
        try:
            # 选择前3个标签
            selected_tags = [tag["id"] for tag in tags[:3]]
            
            headers = {"Authorization": f"Bearer {self.token}"}
            data = {"tag_ids": selected_tags}
            
            response = self.session.post(
                f"{self.base_url}/api/user/tags", 
                json=data, 
                headers=headers
            )
            
            if response.status_code == 200:
                result = response.json()
                if result.get("code") == 0:
                    print(f"✅ 设置用户标签成功: {selected_tags}")
                    return True
                else:
                    print(f"❌ 设置用户标签失败: {result.get('msg')}")
                    return False
            else:
                print(f"❌ 设置用户标签请求失败: {response.status_code}")
                return False
                
        except Exception as e:
            print(f"❌ 设置用户标签异常: {e}")
            return False
    
    def test_get_recommendations(self):
        """测试获取推荐内容"""
        print("🔍 测试获取推荐内容...")
        
        if not self.token:
            print("❌ 用户未登录")
            return False
        
        try:
            headers = {"Authorization": f"Bearer {self.token}"}
            data = {
                "page": 1,
                "size": 10,
                "use_cache": True
            }
            
            response = self.session.post(
                f"{self.base_url}/api/recommendations", 
                json=data, 
                headers=headers
            )
            
            if response.status_code == 200:
                result = response.json()
                if result.get("success"):
                    recommendations = result.get("data", {}).get("recommendations", [])
                    print(f"✅ 获取推荐内容成功，共 {len(recommendations)} 条")
                    
                    # 打印推荐内容详情
                    for i, rec in enumerate(recommendations[:3]):
                        print(f"   {i+1}. {rec.get('title', '无标题')}")
                        print(f"      作者: {rec.get('author_nickname', '匿名')}")
                        print(f"      标签: {', '.join(rec.get('tag_names', []))}")
                        print(f"      互动: 👍{rec.get('like_count', 0)} 💬{rec.get('comment_count', 0)} 👀{rec.get('view_count', 0)}")
                    
                    return recommendations
                else:
                    print(f"❌ 获取推荐内容失败: {result.get('message')}")
                    return []
            else:
                print(f"❌ 获取推荐内容请求失败: {response.status_code}")
                return []
                
        except Exception as e:
            print(f"❌ 获取推荐内容异常: {e}")
            return []
    
    def test_record_behavior(self, content_id):
        """测试记录用户行为"""
        print("🔍 测试记录用户行为...")
        
        if not self.token:
            print("❌ 用户未登录")
            return False
        
        try:
            headers = {"Authorization": f"Bearer {self.token}"}
            params = {
                "content_id": content_id,
                "behavior_type": "view"
            }
            
            response = self.session.post(
                f"{self.base_url}/api/recommendations/behavior", 
                params=params, 
                headers=headers
            )
            
            if response.status_code == 200:
                result = response.json()
                if result.get("success"):
                    print("✅ 记录用户行为成功")
                    return True
                else:
                    print(f"❌ 记录用户行为失败: {result.get('message')}")
                    return False
            else:
                print(f"❌ 记录用户行为请求失败: {response.status_code}")
                return False
                
        except Exception as e:
            print(f"❌ 记录用户行为异常: {e}")
            return False
    
    def test_similar_recommendations(self, content_id):
        """测试文本相似推荐"""
        print("🔍 测试文本相似推荐...")
        
        if not self.token:
            print("❌ 用户未登录")
            return False
        
        try:
            headers = {"Authorization": f"Bearer {self.token}"}
            data = {
                "content_id": content_id,
                "size": 5,
                "min_score": 0.1
            }
            
            response = self.session.post(
                f"{self.base_url}/api/recommendations/similar", 
                json=data, 
                headers=headers
            )
            
            if response.status_code == 200:
                result = response.json()
                if result.get("success"):
                    recommendations = result.get("data", {}).get("recommendations", [])
                    print(f"✅ 获取相似推荐成功，共 {len(recommendations)} 条")
                    return recommendations
                else:
                    print(f"❌ 获取相似推荐失败: {result.get('message')}")
                    return []
            else:
                print(f"❌ 获取相似推荐请求失败: {response.status_code}")
                return []
                
        except Exception as e:
            print(f"❌ 获取相似推荐异常: {e}")
            return []
    
    def test_hot_content(self, tag_id):
        """测试标签热门内容"""
        print("🔍 测试标签热门内容...")
        
        if not self.token:
            print("❌ 用户未登录")
            return False
        
        try:
            headers = {"Authorization": f"Bearer {self.token}"}
            params = {"size": 5}
            
            response = self.session.get(
                f"{self.base_url}/api/recommendations/hot/{tag_id}", 
                params=params, 
                headers=headers
            )
            
            if response.status_code == 200:
                result = response.json()
                if result.get("success"):
                    recommendations = result.get("data", {}).get("recommendations", [])
                    print(f"✅ 获取热门内容成功，共 {len(recommendations)} 条")
                    return recommendations
                else:
                    print(f"❌ 获取热门内容失败: {result.get('message')}")
                    return []
            else:
                print(f"❌ 获取热门内容请求失败: {response.status_code}")
                return []
                
        except Exception as e:
            print(f"❌ 获取热门内容异常: {e}")
            return []
    
    def run_full_test(self):
        """运行完整测试"""
        print("🚀 开始前后端联调测试")
        print("=" * 50)
        
        # 1. 测试后端健康状态
        if not self.test_backend_health():
            return False
        
        # 2. 测试用户登录
        if not self.test_user_login():
            return False
        
        # 3. 测试获取标签
        tags = self.test_get_tags()
        if not tags:
            print("❌ 无法获取标签，测试终止")
            return False
        
        # 4. 测试设置用户标签
        if not self.test_set_user_tags(tags):
            return False
        
        # 5. 测试获取推荐内容
        recommendations = self.test_get_recommendations()
        if not recommendations:
            print("❌ 无法获取推荐内容，测试终止")
            return False
        
        # 6. 测试记录用户行为
        if recommendations:
            content_id = recommendations[0].get("content_id")
            if content_id:
                self.test_record_behavior(content_id)
        
        # 7. 测试文本相似推荐
        if recommendations:
            content_id = recommendations[0].get("content_id")
            if content_id:
                self.test_similar_recommendations(content_id)
        
        # 8. 测试标签热门内容
        if tags:
            tag_id = tags[0].get("id")
            if tag_id:
                self.test_hot_content(tag_id)
        
        print("=" * 50)
        print("🎉 前后端联调测试完成！")
        print("✅ 所有核心功能测试通过")
        
        return True

def main():
    """主函数"""
    tester = IntegrationTester()
    
    print("=== 前后端联调测试 ===")
    print("1. 运行完整测试")
    print("2. 测试后端健康状态")
    print("3. 测试推荐功能")
    
    choice = input("请选择测试类型 (1-3): ").strip()
    
    if choice == "1":
        tester.run_full_test()
    elif choice == "2":
        tester.test_backend_health()
    elif choice == "3":
        if tester.test_user_login():
            tags = tester.test_get_tags()
            if tags:
                tester.test_set_user_tags(tags)
                tester.test_get_recommendations()
    else:
        print("无效选择")

if __name__ == "__main__":
    main()
